package org.water.common.filter;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.water.common.wrapper.XSSRequestWrapper;

import com.alibaba.druid.util.PatternMatcher;
import com.alibaba.druid.util.ServletPathMatcher;

/**
 * xss脚本过滤器
 * @author qzy
 *
 */
public class XssFilter implements Filter {

	/**
	 * 不包含的过滤
	 */
	public static final String PARAM_NAME_EXCLUSIONS             = "exclusions";
	
	static Logger log=LogManager.getLogger(XssFilter.class);
	/**
	 * 上下文路径 
	 */
	protected String  contextPath;
	/**
	 * 不过滤的路径
	 */
	private Set<String> excludesPattern;
	/**
	 * 路径匹配器
	 */
	protected PatternMatcher pathMatcher= new ServletPathMatcher();
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		log.debug("初始化"+XssFilter.class.toString());
		contextPath=filterConfig.getServletContext().getContextPath();
		String exclusions = filterConfig.getInitParameter(PARAM_NAME_EXCLUSIONS);
        if (exclusions != null && exclusions.trim().length() != 0) {
            excludesPattern = new HashSet<String>(Arrays.asList(exclusions.split("\\s*,\\s*")));
        }
        
	}

	/**
	 * xss处理
	 * @param request
	 * @param response
	 * @param chain
	 * @throws IOException
	 * @throws ServletException
	 */
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		log.debug("xss处理");
		if (isExclusion(((HttpServletRequest) request).getRequestURI())) {
            chain.doFilter(request, response);
            return;
        }
		chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
	}

	@Override
	public void destroy() {
		log.debug("初始化"+XssFilter.class.toString());
	}

	/**
	 * 是否为排除过滤的路径 
	 * @param requestURI
	 * @return
	 */
	public boolean isExclusion(String requestURI) {
        if (excludesPattern == null || requestURI == null) {
            return false;
        }

        if (contextPath != null && requestURI.startsWith(contextPath)) {
            requestURI = requestURI.substring(contextPath.length());
            if (!requestURI.startsWith("/")) {
                requestURI = "/" + requestURI;
            }
        }

        for (String pattern : excludesPattern) {
            if (pathMatcher.matches(pattern, requestURI)) {
                return true;
            }
        }

        return false;
    }
}
